Job 和 Cronjob 的使用

上节课我们学习了Pod自动伸缩的方法,我们使用到了HPA这个资源对象,我们在后面的课程中还会和大家接触到HPA的。今天我们来给大家介绍另外一类资源对象:Job,我们在日常的工作中经常都会遇到一些需要进行批量数据处理和分析的需求,当然也会有按时间来进行调度的工作,在我们的Kubernetes集群中为我们提供了JobCronJob两种资源对象来应对我们的这种需求。

Job负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。而CronJob则就是在Job上加上了时间调度。

Job

我们用Job这个资源对象来创建一个任务,我们定一个Job来执行一个倒计时的任务,定义YAML文件:

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: job-demo
  5. spec:
  6. template:
  7. metadata:
  8. name: job-demo
  9. spec:
  10. restartPolicy: Never
  11. containers:
  12. - name: counter
  13. image: busybox
  14. command:
  15. - "bin/sh"
  16. - "-c"
  17. - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

注意JobRestartPolicy仅支持NeverOnFailure两种,不支持Always,我们知道Job就相当于来执行一个批处理任务,执行完就结束了,如果支持Always的话是不是就陷入了死循环了?

然后来创建该Job,保存为job-demo.yaml

  1. $ kubectl create -f ./job.yaml
  2. job "job-demo" created

然后我们可以查看当前的Job资源对象:

  1. $ kubectl get jobs

注意查看我们的Pod的状态,同样我们可以通过kubectl logs来查看当前任务的执行结果。

CronJob

CronJob其实就是在Job的基础上加上了时间调度,我们可以:在给定的时间点运行一个任务,也可以周期性地在给定时间点运行。这个实际上和我们Linux中的crontab就非常类似了。

一个CronJob对象其实就对应中crontab文件中的一行,它根据配置的时间格式周期性地运行一个Job,格式和crontab也是一样的。

crontab的格式如下:

分 时 日 月 星期 要运行的命令
第1列分钟0~59
第2列小时0~23)
第3列日1~31
第4列月1~12
第5列星期0~7(0和7表示星期天)
第6列要运行的命令

现在,我们用CronJob来管理我们上面的Job任务,

  1. apiVersion: batch/v2alpha1
  2. kind: CronJob
  3. metadata:
  4. name: cronjob-demo
  5. spec:
  6. schedule: "*/1 * * * *"
  7. jobTemplate:
  8. spec:
  9. template:
  10. spec:
  11. restartPolicy: OnFailure
  12. containers:
  13. - name: hello
  14. image: busybox
  15. args:
  16. - "bin/sh"
  17. - "-c"
  18. - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"

我们这里的KindCronJob了,要注意的是.spec.schedule字段是必须填写的,用来指定任务运行的周期,格式就和crontab一样,另外一个字段是.spec.jobTemplate, 用来指定需要运行的任务,格式当然和Job是一致的。还有一些值得我们关注的字段.spec.successfulJobsHistoryLimit.spec.failedJobsHistoryLimit,表示历史限制,是可选的字段。它们指定了可以保留多少完成和失败的Job,默认没有限制,所有成功和失败的Job都会被保留。然而,当运行一个Cron Job时,Job可以很快就堆积很多,所以一般推荐设置这两个字段的值。如果设置限制的值为 0,那么相关类型的Job完成后将不会被保留。

接下来我们来创建这个cronjob

  1. $ kubectl create -f cronjob-demo.yaml
  2. cronjob "cronjob-demo" created

当然,也可以用kubectl run来创建一个CronJob

  1. kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
  2. $ kubectl get cronjob
  3. NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
  4. hello */1 * * * * False 0 <none>
  5. $ kubectl get jobs
  6. NAME DESIRED SUCCESSFUL AGE
  7. hello-1202039034 1 1 49s
  8. $ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items..metadata.name} -a)
  9. $ kubectl logs $pods
  10. Mon Aug 29 21:34:09 UTC 2016
  11. Hello from the Kubernetes cluster
  1. $ kubectl delete cronjob hello
  2. cronjob "hello" deleted

一旦不再需要 Cron Job,简单地可以使用 kubectl 命令删除它:

  1. $ kubectl delete cronjob hello
  2. cronjob "hello" deleted

这将会终止正在创建的 Job。然而,运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。为了清理那些 Job 和 Pod,需要列出该 Cron Job 创建的全部 Job,然后删除它们:

  1. $ kubectl get jobs
  2. NAME DESIRED SUCCESSFUL AGE
  3. hello-1201907962 1 1 11m
  4. hello-1202039034 1 1 8m
  5. ...
  6. $ kubectl delete jobs hello-1201907962 hello-1202039034 ...
  7. job "hello-1201907962" deleted
  8. job "hello-1202039034" deleted
  9. ...

一旦 Job 被删除,由 Job 创建的 Pod 也会被删除。注意,所有由名称为 “hello” 的 Cron Job 创建的 Job 会以前缀字符串 “hello-” 进行命名。如果想要删除当前 Namespace 中的所有 Job,可以通过命令 kubectl delete jobs —all 立刻删除它们。